<!--
  ScenicSpotManagement.vue

  景点管理页面组件

  该组件是东营旅游路线规划Web客户端的核心功能页面，提供景点、道路和区域的管理功能，
  包括添加、编辑、删除和查看详情等操作。使用ArcGIS API实现地图功能，Element Plus提供UI组件。
  集成了性能测试工具，监控各操作的响应时间。
-->
<script setup lang="ts">
/**
 * Vue核心功能导入
 */
import { ref, onMounted } from 'vue'

/**
 * Element Plus组件和类型导入
 * 提供UI界面所需的各种组件和类型定义
 */
import {
  ElButton,      // 按钮组件
  ElMenu,        // 菜单组件
  ElMenuItem,    // 菜单项组件
  ElMessage,     // 消息提示组件
  ElSubMenu,     // 子菜单组件
  genFileId,     // 生成文件ID的工具函数
  ElMessageBox, // 消息对话框组件
  type FormInstance,    // 表单实例类型
  type UploadFile,      // 上传文件类型
  type UploadInstance,  // 上传组件实例类型
  type UploadProps,     // 上传组件属性类型
  type UploadRawFile,   // 原始上传文件类型
} from 'element-plus'

/**
 * 性能测试工具导入
 * 用于监控和记录各操作的执行时间
 */
import performanceTest from '@/utils/PerformanceTest'

/**
 * ArcGIS核心地图组件导入
 */
import Map from '@arcgis/core/Map'
import MapView from '@arcgis/core/views/MapView'
/**
 * ArcGIS图层和图形组件导入
 */
import FeatureLayer from '@arcgis/core/layers/FeatureLayer'        // 要素图层，用于管理景点、道路和区域数据
import Graphic from '@arcgis/core/Graphic'                         // 图形对象，用于创建和操作地图要素
import GraphicsLayer from '@arcgis/core/layers/GraphicsLayer.js'   // 图形图层，用于临时绘制操作
import FeatureLayerView from '@arcgis/core/views/Layers/FeatureLayerView.js' // 要素图层视图，用于高亮显示

/**
 * ArcGIS几何和查询组件导入
 */
import Geometry from '@arcgis/core/geometry/Geometry.js'           // 几何基类，用于表示空间几何
import Query from '@arcgis/core/rest/support/Query.js'             // 空间查询支持类
import FeatureSet from '@arcgis/core/rest/support/FeatureSet.js'   // 要素集合，存储查询结果

/**
 * ArcGIS符号和渲染器导入
 */
import SimpleRenderer from "@arcgis/core/renderers/SimpleRenderer.js"      // 简单渲染器
import SimpleMarkerSymbol from "@arcgis/core/symbols/SimpleMarkerSymbol.js" // 点符号
import SimpleLineSymbol from "@arcgis/core/symbols/SimpleLineSymbol.js"     // 线符号

/**
 * ArcGIS工具和辅助类导入
 */
import Sketch from '@arcgis/core/widgets/Sketch.js'                // 草图工具，用于绘制几何图形
import Handles from '@arcgis/core/core/Handles.js'                 // 句柄管理器，用于管理高亮显示

/**
 * 自定义工具和API导入
 */
import gaodeLayer from '@/utils/GaoDeBaseLayer'                    // 高德地图底图
import { compressImage, formatFileSize, getBase64Size } from '@/utils/CompressImage' // 图片压缩工具

/**
 * 类型定义导入
 */
import { type RoadType, type SpotType, type AreaType } from '@/types/public' // 景点、道路和区域的类型定义

/**
 * Element Plus图标导入
 */
import { List, MoonNight, Picture } from '@element-plus/icons-vue'          // 列表、月夜、图片图标
import { Location, Plus, Edit, Share, Crop } from '@element-plus/icons-vue'  // 位置、添加、编辑、分享、裁剪图标
import { Close, Aim, PictureFilled } from '@element-plus/icons-vue'          // 关闭、瞄准、图片填充图标

/**
 * UI状态和引用变量
 */
const mapViewContainer = ref<HTMLDivElement>()                           // 地图视图容器的DOM引用
const selectedFeatureType = ref<string | null>(null)                     // 当前选中的要素类型(点/线/面)
const DetailDrawer = ref(false)                                          // 景点详情抽屉的显示状态
const dataDrawer = ref(false)                                            // 景点表单抽屉的显示状态
const isEdit = ref(false)                                                // 是否处于编辑模式
const isDrawing = ref(false)                                             // 是否正在绘制状态
const multiSelect = ref(false)                                           // 是否处于多选模式
const direction = 'rtl'                                                  // 抽屉方向(从右到左)

/**
 * 数据存储变量
 */
const spotData = ref<SpotType | null>(null)                              // 当前选中的景点数据
const roadData = ref<RoadType | null>(null)                              // 当前选中的道路数据
const areaData = ref<AreaType | null>(null)                              // 当前选中的区域数据
const multiSelectTableData = ref<SpotType[] | RoadType[] | AreaType[]>([]) // 多选结果数据列表

/**
 * 表单相关变量
 */
const DataForm = ref<FormInstance>()                                     // 表单实例引用
const uploadRef = ref<UploadInstance>()                                  // 文件上传组件实例引用

/**
 * 景点表单数据
 * 用于添加或编辑景点信息
 */
const spotFormData = ref<SpotType>({
  SpotName: '',                // 景点名称
  SpotIntroduction: '',        // 景点介绍
  IntroduceImageBase64: '',    // 景点图片(Base64格式)
  spotType: '游玩',            // 景点类型，默认为"游玩"
})

/**
 * 道路表单数据
 * 用于添加或编辑道路信息
 */
const roadFormData = ref<RoadType>({
  RoadName: '',                // 道路名称
  RoadIntroduction: '',        // 道路介绍
  IntroduceImageBase64: '',    // 道路图片(Base64格式)
})

/**
 * 区域表单数据
 * 用于添加或编辑区域信息
 */
const areaFormData = ref<AreaType>({
  AreaName: '',                // 区域名称
  AreaIntroduction: '',        // 区域介绍
  IntroduceImageBase64: '',    // 区域图片(Base64格式)
})

/**
 * 地图交互相关变量
 * 这些变量不需要响应式，使用普通let声明
 */
let ScenicGeometry: Geometry                                             // 当前操作的几何图形
let editFeatureOID: number | null = null                                 // 编辑要素的对象ID
let clickHandler: IHandle | null = null                                  // 地图点击事件处理器
let currentSketch: Sketch | null = null                                  // 当前绘制工具实例
let clickQueryResult: FeatureSet | null = null                           // 点击查询结果集
let dataDrawerType: string | null = null                                 // 当前数据类型('spot'/'road'/'area')
let detailTitle: string | null = null                                    // 详情对话框标题

/**
 * 高亮显示管理器
 * 用于管理地图上要素的高亮效果
 */
const highlightHandle: Handles = new Handles()                           // 高亮显示句柄管理器

/**
 * 景点图层定义
 * 使用点符号表示景点位置
 */
const scenicSpotLayer = new FeatureLayer({
  url: 'https://services5.arcgis.com/QHJE36ge0b3AlcS2/arcgis/rest/services/szwhy_dianxianmian/FeatureServer/0', // 景点服务URL
  outFields: ['*'], // 获取所有字段
  renderer: new SimpleRenderer({
    symbol: new SimpleMarkerSymbol({
      color: [255, 0, 0, 0.8], // 鲜红色(#FF0000)，透明度为0.8，用于突出显示景点位置
      size: 8, // 点大小
      outline: {
        color: [0, 0, 0, 1], // 纯黑色(#000000)边框，不透明，增强可见性
        width: 1 // 边框宽度
      }
    })
  })
});

/**
 * 道路图层定义
 * 使用线符号表示景点间的路线
 */
const scenicRoadLayer = new FeatureLayer({
  url: 'https://services5.arcgis.com/QHJE36ge0b3AlcS2/arcgis/rest/services/szwhy_dianxianmian/FeatureServer/1', // 道路服务URL
  outFields: ['*'], // 获取所有字段
  renderer: new SimpleRenderer({
    symbol: new SimpleLineSymbol({
      color: [171, 68, 68, 0.8], // 砖红色(#AB4444)，透明度为0.8，用于表示连接景点的道路
      width: 3, // 线宽
    })
  })
});

/**
 * 区域图层定义
 * 使用面符号表示景区范围
 */
const scenicAreaLayer = new FeatureLayer({
  url: 'https://services5.arcgis.com/QHJE36ge0b3AlcS2/arcgis/rest/services/szwhy_dianxianmian/FeatureServer/2', // 区域服务URL
  outFields: ['*'], // 获取所有字段
});

/**
 * 地图实例创建
 * 使用高德地图作为底图
 */
const map = new Map({
  basemap: {
    baseLayers: [gaodeLayer], // 使用高德地图作为底图
  },
});

// 将所有业务图层添加到地图
map.addMany([scenicSpotLayer, scenicRoadLayer, scenicAreaLayer]);

/**
 * 绘制图层
 * 用于临时存储用户绘制的几何图形
 */
const sketchLayer = new GraphicsLayer();
map.add(sketchLayer);

/**
 * 地图视图实例
 * 控制地图的显示和交互
 */
const view = new MapView({
  map, // 关联的地图实例
  center: [118.45786183624148, 37.04540349081432], // 初始中心点坐标(东营市广饶县)
  zoom: 15, // 初始缩放级别
});

/**
 * 启动绘制功能
 * 允许用户在地图上绘制点、线或面几何图形
 *
 * @param geometryType - 要绘制的几何类型('point'|'polyline'|'polygon')
 * @param isUpdate - 是否为更新现有要素的几何(true)还是创建新要素(false)
 * @returns Promise - 在绘制完成时解析
 */
const startDrawing = (
  geometryType: 'point' | 'polyline' | 'polygon',
  isUpdate: boolean = false,
): Promise<void> => {
  return new Promise((resolve) => {
    // 设置绘制状态
    isDrawing.value = true

    // 清除绘制图层中的现有内容
    sketchLayer.removeAll()

    // 提示用户开始绘制
    ElMessage.info(`请用鼠标绘制`)

    // 创建绘制工具实例
    const sketch = new Sketch({
      view: view,           // 关联到当前地图视图
      layer: sketchLayer,   // 绘制结果存储在sketchLayer
      visible: false,       // 不显示工具UI，只使用其功能
    })

    // 保存当前绘制工具实例，以便后续可以取消
    currentSketch = sketch

    // 开始绘制指定类型的几何
    sketch.create(geometryType, { mode: 'click' })

    // 监听绘制事件
    sketch.on('create', function (event) {
      // 当绘制完成时
      if (event.state === 'complete') {
        // 保存绘制的几何图形
        ScenicGeometry = event.graphic.geometry
        console.log('完成的几何图形:', ScenicGeometry)

        // 如果不是更新模式，则显示表单让用户输入属性
        if (!isUpdate) {
          dataDrawer.value = true
        }

        // 重置绘制状态
        isDrawing.value = false
        currentSketch = null

        // 取消绘制工具，关闭绘图界面
        sketch.cancel()

        // 解析Promise，表示绘制完成
        resolve()
      }
    })
  })
}

/**
 * 添加景点功能
 * 允许用户在地图上绘制点并添加景点信息
 */
const addScenicSpot = () => {
  // 开始性能计时
  performanceTest.startTimer('addScenicSpot');

  // 清除之前的高亮显示
  highlightHandle.removeAll()

  // 设置为新增模式
  isEdit.value = false
  dataDrawerType = 'spot'

  // 重置景点表单数据
  spotFormData.value = {
    SpotName: '',
    SpotIntroduction: '',
    IntroduceImageBase64: '',
    spotType: '游玩', // 默认类型
  }

  // 提示用户开始绘制
  ElMessage.info('请用鼠标绘点')

  // 启动点绘制
  startDrawing('point')
    .then(() => {
      // 绘制成功，结束性能计时
      performanceTest.endTimer('addScenicSpot');
    })
    .catch(() => {
      // 绘制失败，记录错误
      performanceTest.endTimer('addScenicSpot', { error: '绘制失败' });
    });
}

/**
 * 添加道路功能
 * 允许用户在地图上绘制线并添加道路信息
 */
const addScenicRoad = () => {
  // 开始性能计时
  performanceTest.startTimer('addScenicRoad');

  // 清除之前的高亮显示
  highlightHandle.removeAll()

  // 设置为新增模式
  isEdit.value = false
  dataDrawerType = 'road'

  // 重置道路表单数据
  roadFormData.value = {
    RoadName: '',
    RoadIntroduction: '',
    IntroduceImageBase64: '',
  }

  // 提示用户开始绘制
  ElMessage.info('请用鼠标绘线')

  // 启动线绘制
  startDrawing('polyline')
    .then(() => {
      // 绘制成功，结束性能计时
      performanceTest.endTimer('addScenicRoad');
    })
    .catch(() => {
      // 绘制失败，记录错误
      performanceTest.endTimer('addScenicRoad', { error: '绘制失败' });
    });
}

/**
 * 添加区域功能
 * 允许用户在地图上绘制多边形并添加区域信息
 */
const addScenicArea = () => {
  // 开始性能计时
  performanceTest.startTimer('addScenicArea');

  // 清除之前的高亮显示
  highlightHandle.removeAll()

  // 设置为新增模式
  isEdit.value = false
  dataDrawerType = 'area'

  // 重置区域表单数据
  areaFormData.value = {
    AreaName: '',
    AreaIntroduction: '',
    IntroduceImageBase64: '',
  }

  // 提示用户开始绘制
  ElMessage.info('请用鼠标绘制区域')

  // 启动多边形绘制
  startDrawing('polygon')
    .then(() => {
      // 绘制成功，结束性能计时
      performanceTest.endTimer('addScenicArea');
    })
    .catch(() => {
      // 绘制失败，记录错误
      performanceTest.endTimer('addScenicArea', { error: '绘制失败' });
    });
}

/**
 * 取消绘制功能
 * 允许用户中断当前的绘制操作
 */
const cancelDrawing = () => {
  // 如果存在当前绘制实例，取消它
  if (currentSketch) {
    currentSketch.cancel()
    currentSketch = null
  }

  // 重置绘制状态
  isDrawing.value = false

  // 清除绘制图层
  sketchLayer.removeAll()

  // 提示用户
  ElMessage.info('已退出绘制模式')
}

/**
 * 更新要素几何信息
 * 允许用户重新绘制已有要素的几何形状
 *
 * @param geometryDrawerType - 要更新的要素类型('spot'|'road'|'area')
 */
const updateScenicGeometry = async (geometryDrawerType: 'spot' | 'road' | 'area') => {
  // 弹出确认对话框，确认用户是否要更新几何信息
  const confirm = await ElMessageBox.confirm('是否要更新景点的几何信息？')
  if (!confirm) return

  // 关闭详情抽屉
  DetailDrawer.value = false

  // 设置为编辑模式
  isEdit.value = true

  // 根据不同类型执行不同的更新操作
  if (geometryDrawerType === 'spot') {
    // 更新景点几何
    await startDrawing('point', true) // 启动点绘制，标记为更新模式
    editFeatureOID = spotData.value!.FID! // 保存要编辑的对象ID
    submitFeature(scenicSpotLayer, { SpotName: spotData.value!.SpotName }, '景点')
  } else if (geometryDrawerType === 'road') {
    // 更新道路几何
    await startDrawing('polyline', true) // 启动线绘制，标记为更新模式
    editFeatureOID = roadData.value!.FID! // 保存要编辑的对象ID
    submitFeature(scenicRoadLayer, { RoadName: roadData.value!.RoadName }, '道路')
  } else if (geometryDrawerType === 'area') {
    // 更新区域几何
    await startDrawing('polygon', true) // 启动面绘制，标记为更新模式
    editFeatureOID = areaData.value!.FID! // 保存要编辑的对象ID
    submitFeature(scenicAreaLayer, { AreaName: areaData.value!.AreaName }, '区域')
  }
}

/**
 * 更新要素属性信息
 * 允许用户编辑已有要素的属性数据(名称、描述、图片等)
 */
const updateScenicDetail = () => {
  // 关闭详情抽屉
  DetailDrawer.value = false

  // 根据当前数据类型，将现有数据复制到表单中
  if (dataDrawerType === 'spot') {
    // 更新景点表单数据
    spotFormData.value = spotData.value!
  } else if (dataDrawerType === 'road') {
    // 更新道路表单数据
    roadFormData.value = roadData.value!
  } else if (dataDrawerType === 'area') {
    // 更新区域表单数据
    areaFormData.value = areaData.value!
  }

  // 显示数据编辑抽屉
  dataDrawer.value = true

  // 设置为编辑模式
  isEdit.value = true
}

/**
 * 删除要素功能
 * 允许用户删除选中的景点、道路或区域
 *
 * @param deleteFeatureType - 要删除的要素类型('spot'|'road'|'area')
 */
const deleteScenic = (deleteFeatureType: 'spot' | 'road' | 'area') => {
  // 根据不同类型执行不同的删除操作
  if (deleteFeatureType === 'spot') {
    // 删除景点
    deleteFeature(scenicSpotLayer, spotData.value?.FID!, '景点')
  } else if (deleteFeatureType === 'road') {
    // 删除道路
    deleteFeature(scenicRoadLayer, roadData.value?.FID!, '道路')
  } else if (deleteFeatureType === 'area') {
    // 删除区域
    deleteFeature(scenicAreaLayer, areaData.value?.FID!, '区域')
  }

  // 关闭详情抽屉
  DetailDrawer.value = false
}

/**
 * 处理地图点击查询要素
 * 实现点击地图查询并显示要素详情的功能
 *
 * @param layer - 要查询的图层
 * @param featureType - 要素类型名称('景点'|'道路'|'区域')
 */
const handleClickToEditFeature = async (layer: FeatureLayer, featureType: string) => {
  // 注册地图点击事件
  clickHandler = view.on('click', async function (event) {
    // 创建性能计时器名称
    const timerName = `query${featureType}`;
    // 开始性能计时
    performanceTest.startTimer(timerName, { featureType });

    // 获取点击位置
    const mapPoint = event.mapPoint.clone()

    // 构建空间查询参数
    const query = new Query()
    query.geometry = mapPoint           // 查询点
    query.distance = 3              // 缓冲距离(米)
    query.units = 'meters'              // 距离单位
    query.spatialRelationship = 'intersects' // 空间关系为相交
    query.returnGeometry = true         // 返回几何信息
    query.outFields = ['*']             // 返回所有字段

    try {
      // 执行空间查询
      clickQueryResult = await layer.queryFeatures(query)

      // 设置多选对话框标题
      detailTitle = `该区域存在多个${featureType}，请选择具体的一个${featureType}，我们将为您展示它的详细信息`

      // 处理查询结果
      if (clickQueryResult.features.length > 0) {
        // 查询成功后移除点击事件，防止重复触发
        clickHandler?.remove()
        clickHandler = null

        // 如果找到多个要素，显示选择列表
        if (clickQueryResult.features.length > 1) {
          multiSelect.value = true // 激活多选模式

          // 根据要素类型设置多选数据
          if (featureType === '景点') {
            multiSelectTableData.value = clickQueryResult.features.map(
              (feature) => feature.attributes as SpotType,
            )
          } else if (featureType === '道路') {
            multiSelectTableData.value = clickQueryResult.features.map(
              (feature) => feature.attributes as RoadType,
            )
          } else if (featureType === '区域') {
            multiSelectTableData.value = clickQueryResult.features.map(
              (feature) => feature.attributes as AreaType,
            )
          }

          // 记录性能数据 - 多个结果
          performanceTest.endTimer(timerName, { success: true, featuresCount: clickQueryResult.features.length });
        } else {
          // 只有一个要素时直接显示详情
          highlightFeature(layer, clickQueryResult.features[0]) // 高亮显示要素

          // 根据要素类型设置详情数据
          if (featureType === '景点') {
            spotData.value = clickQueryResult.features[0].attributes as SpotType
            editFeatureOID = clickQueryResult.features[0].attributes.FID as number
          } else if (featureType === '道路') {
            roadData.value = clickQueryResult.features[0].attributes as RoadType
            editFeatureOID = clickQueryResult.features[0].attributes.FID as number
          } else if (featureType === '区域') {
            areaData.value = clickQueryResult.features[0].attributes as AreaType
            editFeatureOID = clickQueryResult.features[0].attributes.FID as number
          }

          // 保存几何信息，用于后续编辑
          ScenicGeometry = clickQueryResult.features[0].geometry

          // 显示详情抽屉
          DetailDrawer.value = true

          // 记录性能数据 - 单个结果
          performanceTest.endTimer(timerName, { success: true, featuresCount: 1 });
        }
      } else {
        // 未找到要素时提示用户
        ElMessage.info(`未找到对应的${featureType}`)

        // 记录性能数据 - 无结果
        performanceTest.endTimer(timerName, { success: true, featuresCount: 0 });
      }
    } catch (error) {
      // 错误处理
      console.error(`查询${featureType}错误:`, error);
      ElMessage.error(`查询${featureType}失败，请重试`);

      // 记录性能数据 - 查询失败
      performanceTest.endTimer(timerName, {
        success: false,
        error: error instanceof Error ? error.message : String(error)
      });
    }
  })
}

/**
 * 编辑景点功能
 * 允许用户选择并编辑现有景点
 */
const editScenicSpot = () => {
  // 清除之前的高亮显示
  highlightHandle.removeAll()

  // 设置当前数据类型为景点
  dataDrawerType = 'spot'

  // 提示用户操作方式
  ElMessage.info('请点击一个景点进行编辑')

  // 启动点击查询功能，查询景点图层
  handleClickToEditFeature(scenicSpotLayer, '景点')
}

/**
 * 编辑道路功能
 * 允许用户选择并编辑现有道路
 */
const editScenicRoad = () => {
  // 清除之前的高亮显示
  highlightHandle.removeAll()

  // 设置当前数据类型为道路
  dataDrawerType = 'road'

  // 提示用户操作方式
  ElMessage.info('请点击一个景点道路进行编辑')

  // 启动点击查询功能，查询道路图层
  handleClickToEditFeature(scenicRoadLayer, '道路')
}

/**
 * 编辑区域功能
 * 允许用户选择并编辑现有区域
 */
const editScenicArea = () => {
  // 清除之前的高亮显示
  highlightHandle.removeAll()

  // 设置当前数据类型为区域
  dataDrawerType = 'area'

  // 提示用户操作方式
  ElMessage.info('请点击一个景点区域进行编辑')

  // 启动点击查询功能，查询区域图层
  handleClickToEditFeature(scenicAreaLayer, '区域')
}

/**
 * 多选结果处理功能
 * 当查询返回多个要素时，用户从列表中选择一个要素后的处理函数
 *
 * @param row - 用户选择的要素数据(景点/道路/区域)
 */
const multiSelectHandle = (row: SpotType | RoadType | AreaType) => {
  // 根据选择项的类型进行不同处理
  if ('SpotName' in row) {
    // 处理景点类型
    spotData.value = row as SpotType // 设置选中的景点数据
    editFeatureOID = row.FID!   // 保存对象ID用于编辑

    // 查找并高亮显示对应的要素
    clickQueryResult?.features.forEach((feature) => {
      if (feature.attributes.FID === row.FID) {
        ScenicGeometry = feature.geometry // 保存几何信息
        highlightFeature(scenicSpotLayer, feature) // 高亮显示
      }
    })
  } else if ('RoadName' in row) {
    // 处理道路类型
    roadData.value = row as RoadType // 设置选中的道路数据
    editFeatureOID = row.FID!   // 保存对象ID用于编辑

    // 查找并高亮显示对应的要素
    clickQueryResult?.features.forEach((feature) => {
      if (feature.attributes.FID === row.FID) {
        ScenicGeometry = feature.geometry // 保存几何信息
        highlightFeature(scenicRoadLayer, feature) // 高亮显示
      }
    })
  } else if ('AreaName' in row) {
    // 处理区域类型
    areaData.value = row as AreaType // 设置选中的区域数据
    editFeatureOID = row.FID!   // 保存对象ID用于编辑

    // 查找并高亮显示对应的要素
    clickQueryResult?.features.forEach((feature) => {
      if (feature.attributes.FID === row.FID) {
        ScenicGeometry = feature.geometry // 保存几何信息
        highlightFeature(scenicAreaLayer, feature) // 高亮显示
      }
    })
  }

  // 显示详情抽屉，关闭多选对话框
  DetailDrawer.value = true
  multiSelect.value = false
}

/**
 * 高亮显示要素功能
 * 在地图上高亮显示选中的要素
 *
 * @param layer - 要素所在的图层
 * @param feature - 要高亮显示的要素
 */
const highlightFeature = async (layer: FeatureLayer, feature: Graphic) => {
  // 获取图层视图
  const featureLayerView = (await view.whenLayerView(layer)) as FeatureLayerView

  // 创建高亮效果
  const highlight = featureLayerView.highlight(feature)

  // 将高亮句柄添加到管理器中，便于后续清除
  highlightHandle.add(highlight)
}

/**
 * 处理要素类型选择
 * 当用户在菜单中选择不同类型时触发
 *
 * @param type - 选中的类型
 */
const handleFeatureTypeSelection = (type: string) => {
  // 更新选中的要素类型
  selectedFeatureType.value = type
}

/**
 * 抽屉关闭处理函数
 * 在抽屉关闭前执行清理操作
 *
 * @param done - 完成关闭的回调函数
 */
const drawerClose = (done: () => void) => {
  // 清除绘制图层中的内容
  sketchLayer.removeAll()

  // 执行关闭回调
  done()
}

/**
 * 文件选择处理函数
 * 处理用户选择的图片文件，包括类型验证、压缩和转换为Base64
 *
 * @param uploadFile - 上传的文件对象
 */
const onSelectFile = async (uploadFile: UploadFile) => {
  // 验证文件类型，只接受常见图片格式
  if (
    uploadFile.raw?.type !== 'image/jpeg' &&
    uploadFile.raw?.type !== 'image/png' &&
    uploadFile.raw?.type !== 'image/gif' &&
    uploadFile.raw?.type !== 'image/bmp'
  ) {
    ElMessage.error('请选择正确的图片文件')
    return
  }

  try {
    // 处理图片：大于1MB时进行压缩，否则直接转换为Base64
    const base64Image =
      uploadFile.raw.size > 1024 * 1024
        ? await compressImage(uploadFile.raw) // 使用压缩函数处理大图片
        : await new Promise<string>((resolve, reject) => {
            // 直接转换为Base64
            const reader = new FileReader()
            reader.readAsDataURL(uploadFile.raw!)
            reader.onload = () => resolve(reader.result?.toString()!)
            reader.onerror = (err) => reject(err)
          })

    // 根据当前数据类型，将Base64图片数据保存到对应表单
    if (dataDrawerType === 'spot') {
      // 保存到景点表单
      spotFormData.value!.IntroduceImageBase64 = base64Image
    } else if (dataDrawerType === 'road') {
      // 保存到道路表单
      roadFormData.value!.IntroduceImageBase64 = base64Image
    } else if (dataDrawerType === 'area') {
      // 保存到区域表单
      areaFormData.value!.IntroduceImageBase64 = base64Image
    }

    // 输出压缩后图片的大小信息
    console.log('压缩后大小：', formatFileSize(getBase64Size(base64Image)))
  } catch (e) {
    // 错误处理
    ElMessage.error(e instanceof Error ? e.message : '图片处理失败')
  }
}

/**
 * 处理文件超出限制
 * 当用户尝试上传多个文件时，保留最新的一个
 *
 * @param files - 超出限制的文件列表
 */
const handleExceed: UploadProps['onExceed'] = (files) => {
  // 清除现有文件
  uploadRef.value!.clearFiles()

  // 获取第一个文件
  const file = files[0] as UploadRawFile

  // 生成唯一ID
  file.uid = genFileId()

  // 开始上传新文件
  uploadRef.value!.handleStart(file)
}

/**
 * 删除要素功能
 * 从图层中删除指定的要素
 *
 * @param layer - 要素所在的图层
 * @param deleteFeatureId - 要删除的要素ID
 * @param featureType - 要素类型名称，用于提示信息
 */
const deleteFeature = async (layer: FeatureLayer, deleteFeatureId: number, featureType: string) => {
  // 创建性能计时器名称
  const timerName = `delete${featureType}`;

  // 开始性能计时
  performanceTest.startTimer(timerName, { featureType, deleteFeatureId });

  try {
    // 创建要删除的要素属性对象，只需要FID
    const attributes = {
      FID: deleteFeatureId,
    }

    // 创建一个新的图形对象，只包含属性，不需要几何信息
    const graphic = new Graphic({
      attributes: attributes,
    })

    // 执行删除操作
    const result = await layer.applyEdits({
      deleteFeatures: [graphic], // 指定要删除的要素
    })

    // 检查删除结果
    if (result.deleteFeatureResults?.length > 0) {
      // 删除成功
      ElMessage.success(`${featureType}删除成功`)

      // 刷新图层，更新显示
      layer.refresh()

      // 关闭数据抽屉
      dataDrawer.value = false

      // 记录性能数据 - 删除成功
      performanceTest.endTimer(timerName, { success: true, result });
    } else {
      // 删除失败
      throw new Error('操作失败')
    }
  } catch (error) {
    // 错误处理
    console.error(`${featureType}删除错误:`, error)
    ElMessage.error(error instanceof Error ? error.message : '操作失败，请重试')

    // 记录性能数据 - 删除失败
    performanceTest.endTimer(timerName, {
      success: false,
      error: error instanceof Error ? error.message : String(error)
    });
  }
}

/**
 * 提交要素功能
 * 添加新要素或更新现有要素
 *
 * @param layer - 要素所在的图层
 * @param formData - 要素的属性数据
 * @param featureType - 要素类型名称，用于提示信息
 */
const submitFeature = async (
  layer: FeatureLayer,
  formData: SpotType | RoadType | AreaType,
  featureType: string,
) => {
  // 创建性能计时器名称
  const timerName = `submit${featureType}`;

  // 开始性能计时
  performanceTest.startTimer(timerName, { featureType, isEdit: isEdit.value });

  try {
    // 根据是否为编辑模式，构建不同的属性对象
    const attributes = isEdit.value
      ? {
          // 编辑模式：包含FID和表单数据
          FID: editFeatureOID!,
          ...formData,
        }
      : {
          // 新增模式：只包含表单数据
          ...formData,
        }

    // 创建图形对象，包含几何信息和属性
    const graphic = new Graphic({
      geometry: ScenicGeometry, // 用户绘制的几何图形
      attributes: attributes,   // 构建的属性对象
    })

    // 根据模式执行不同的编辑操作
    const result = await layer.applyEdits({
      ...(isEdit.value
        ? { updateFeatures: [graphic] } // 编辑模式：更新要素
        : { addFeatures: [graphic] }    // 新增模式：添加要素
      ),
    })

    // 检查操作结果
    if (
      (isEdit.value && result.updateFeatureResults?.length > 0) || // 编辑成功
      (!isEdit.value && result.addFeatureResults?.length > 0)      // 添加成功
    ) {
      // 操作成功
      ElMessage.success(`${featureType}信息提交成功`)

      // 刷新图层，更新显示
      layer.refresh()

      // 关闭数据抽屉
      dataDrawer.value = false

      // 记录性能数据 - 提交成功
      performanceTest.endTimer(timerName, { success: true, result });
    } else {
      // 操作失败
      throw new Error('操作失败')
    }
  } catch (error) {
    // 错误处理
    console.error(`${featureType}提交错误:`, error)
    ElMessage.error(error instanceof Error ? error.message : '操作失败，请重试')

    // 记录性能数据 - 提交失败
    performanceTest.endTimer(timerName, {
      success: false,
      error: error instanceof Error ? error.message : String(error)
    });
  } finally {
    // 清理绘制图层，无论成功失败
    sketchLayer.removeAll()
  }
}

/**
 * 表单提交处理函数
 * 验证并提交表单数据到相应的图层
 */
const formSubmit = async () => {
  // 检查表单实例是否存在
  if (!DataForm.value) return

  try {
    // 验证表单数据
    await DataForm.value.validate()

    // 清除绘制图层
    sketchLayer.removeAll()

    // 根据当前数据类型提交到不同图层
    if (dataDrawerType === 'spot') {
      // 提交景点数据
      await submitFeature(scenicSpotLayer, spotFormData.value, '景点')
    } else if (dataDrawerType === 'road') {
      // 提交道路数据
      await submitFeature(scenicRoadLayer, roadFormData.value, '景点道路')
    } else if (dataDrawerType === 'area') {
      // 提交区域数据
      await submitFeature(scenicAreaLayer, areaFormData.value, '景点区域')
    }
  } catch (error) {
    // 错误处理
    console.error('提交错误:', error)
    ElMessage.error(error instanceof Error ? error.message : '操作失败，请重试')
  }
}

/**
 * 组件挂载生命周期钩子
 * 初始化地图和性能监控
 */
onMounted(async () => {
  // 开始地图初始化性能计时
  performanceTest.startTimer('mapInitialization');

  // 设置地图容器和UI
  view.container = mapViewContainer.value!
  view.ui.add('functionPanel', 'top-right')

  // 监听地图加载完成事件
  view.when(() => {
    // 结束地图初始化性能计时
    performanceTest.endTimer('mapInitialization');
    console.log('地图性能报告:', performanceTest.generateReport());
  });

  // 延迟监控资源加载性能
  // 等待5秒后检查资源加载情况，确保大部分资源已开始加载
  setTimeout(() => {
    performanceTest.monitorResourceLoading();
  }, 5000);
})

/**
 * 性能测试相关变量和函数
 */
// 性能测试状态控制
const showPerformancePanel = ref(false) // 控制性能面板显示
const performanceReport = ref<Record<string, any>>({}) // 存储性能报告数据

/**
 * 生成并显示性能报告
 * 收集所有性能测试数据并显示在面板中
 */
const generatePerformanceReport = () => {
  // 获取性能测试报告
  performanceReport.value = performanceTest.generateReport()

  // 显示性能测试面板
  showPerformancePanel.value = true
}

/**
 * 清除性能记录
 * 重置所有性能测试数据
 */
const clearPerformanceRecords = () => {
  // 清除性能测试记录
  performanceTest.clearRecords()

  // 清空报告数据
  performanceReport.value = {}

  // 提示用户
  ElMessage.success('性能测试记录已清除')
}

/**
 * 表单验证规则定义
 */
// 景点表单验证规则
const spotRules = {
  SpotName: [{ required: true, message: '请输入景点名称', trigger: 'blur' }], // 景点名称为必填项
  SpotIntroduction: [{ required: false, message: '请输入景点详情', trigger: 'blur' }], // 景点详情为可选项
  spotType: [{ required: true, message: '请选择景点类型', trigger: 'change' }], // 景点类型为必选项
}

// 道路表单验证规则
const roadRules = {
  RoadName: [{ required: true, message: '请输入路线名称', trigger: 'blur' }], // 路线名称为必填项
  RoadIntroduction: [{ required: false, message: '请输入路线详情', trigger: 'blur' }], // 路线详情为可选项
}

// 区域表单验证规则
const areaRules = {
  AreaName: [{ required: true, message: '请输入区域名称', trigger: 'blur' }], // 区域名称为必填项
  AreaIntroduction: [{ required: false, message: '请输入区域详情', trigger: 'blur' }], // 区域详情为可选项
}
</script>

<template>
  <div ref="mapViewContainer" class="mapViewContainer">
    <div id="functionPanel" class="function-panel">
      <div class="performance-button-container">
        <el-button type="primary" size="small" @click="generatePerformanceReport">
          <el-icon><List /></el-icon>
          性能测试报告
        </el-button>
      </div>
      <el-menu
        :default-active="selectedFeatureType!"
        class="function-menu"
        @select="handleFeatureTypeSelection"
      >
        <el-sub-menu index="point" class="menu-item">
          <template #title>
            <el-icon><Location /></el-icon>
            <span>景点管理</span>
          </template>
          <el-menu-item index="addPoint" @click="addScenicSpot">
            <el-icon><Plus /></el-icon>
            <span>添加景点</span>
          </el-menu-item>
          <el-menu-item index="editPoint" @click="editScenicSpot">
            <el-icon><Edit /></el-icon>
            <span>编辑景点</span>
          </el-menu-item>
        </el-sub-menu>

        <el-sub-menu index="line" class="menu-item">
          <template #title>
            <el-icon><Share /></el-icon>
            <span>路线管理</span>
          </template>
          <el-menu-item index="addLine" @click="addScenicRoad">
            <el-icon><Plus /></el-icon>
            <span>添加路线</span>
          </el-menu-item>
          <el-menu-item index="editLine" @click="editScenicRoad">
            <el-icon><Edit /></el-icon>
            <span>编辑路线</span>
          </el-menu-item>
        </el-sub-menu>

        <el-sub-menu index="area" class="menu-item">
          <template #title>
            <el-icon><Crop /></el-icon>
            <span>区域管理</span>
          </template>
          <el-menu-item index="addArea" @click="addScenicArea">
            <el-icon><Plus /></el-icon>
            <span>添加区域</span>
          </el-menu-item>
          <el-menu-item index="editArea" @click="editScenicArea">
            <el-icon><Edit /></el-icon>
            <span>编辑区域</span>
          </el-menu-item>
        </el-sub-menu>
      </el-menu>
      <!-- 添加绘制状态提示和退出按钮 -->
      <div v-if="isDrawing" class="drawing-controls">
        <div class="drawing-tip">
          <el-icon><Aim /></el-icon>
          <span>正在绘制景点...</span>
        </div>
        <el-button type="warning" size="small" @click="cancelDrawing" class="cancel-button">
          <el-icon><Close /></el-icon>
          退出绘制
        </el-button>
      </div>
    </div>
  </div>
  <!-- 填写景点基础信息的弹窗 -->
  <el-drawer
    v-model="dataDrawer"
    title="填写要素基础信息"
    :direction="direction"
    :before-close="drawerClose"
  >
    <el-form
      v-if="dataDrawerType === 'spot'"
      :model="spotFormData"
      ref="DataForm"
      label-width="120px"
      label-position="left"
      :rules="spotRules"
    >
      <el-form-item label="景点名称" prop="SpotName">
        <el-input v-model="spotFormData!.SpotName" />
      </el-form-item>
      <el-form-item label="景点类型" prop="spotType">
        <el-select v-model="spotFormData!.spotType" placeholder="请选择景点类型">
          <el-option label="游玩" value="游玩" />
          <el-option label="文化" value="文化" />
          <el-option label="度假" value="度假" />
          <el-option label="其他" value="其他" />
        </el-select>
      </el-form-item>
      <el-form-item label="景点详细描述" prop="SpotIntroduction">
        <el-input v-model="spotFormData!.SpotIntroduction" type="textarea" />
      </el-form-item>
      <el-form-item label="景点宣传图片">
        <el-upload
          ref="uploadRef"
          :auto-upload="false"
          class="upload-demo"
          :show-file-list="true"
          :on-exceed="handleExceed"
          :limit="1"
          :on-change="onSelectFile"
          accept=".jpg,.png,.gif,.bmp"
        >
          <template #trigger>
            <el-button type="primary">选择图片</el-button>
          </template>
          <template #tip>
            <div class="el-upload__tip">请选择jpg/png/gif/bmp图片文件</div>
          </template>
        </el-upload>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="formSubmit">确认提交</el-button>
      </el-form-item>
    </el-form>
    <el-form
      v-else-if="dataDrawerType === 'road'"
      :model="roadFormData"
      ref="DataForm"
      label-width="120px"
      label-position="left"
      :rules="roadRules"
    >
      <el-form-item label="路线名称" prop="RoadName">
        <el-input v-model="roadFormData!.RoadName" />
      </el-form-item>
      <el-form-item label="路线详细描述" prop="RoadIntroduction">
        <el-input v-model="roadFormData!.RoadIntroduction" type="textarea" />
      </el-form-item>
      <el-form-item label="路线宣传图片">
        <el-upload
          ref="uploadRef"
          :auto-upload="false"
          class="upload-demo"
          :show-file-list="true"
          :on-exceed="handleExceed"
          :limit="1"
          :on-change="onSelectFile"
          accept=".jpg,.png,.gif,.bmp"
        >
          <template #trigger>
            <el-button type="primary">选择图片</el-button>
          </template>
          <template #tip>
            <div class="el-upload__tip">请选择jpg/png/gif/bmp图片文件</div>
          </template>
        </el-upload>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="formSubmit">确认提交</el-button>
      </el-form-item>
    </el-form>
    <el-form
      v-else-if="dataDrawerType === 'area'"
      :model="areaFormData"
      ref="DataForm"
      label-width="120px"
      label-position="left"
      :rules="areaRules"
    >
      <el-form-item label="区域名称" prop="AreaName">
        <el-input v-model="areaFormData!.AreaName" />
      </el-form-item>
      <el-form-item label="区域详细描述" prop="AreaIntroduction">
        <el-input v-model="areaFormData!.AreaIntroduction" type="textarea" />
      </el-form-item>
      <el-form-item label="区域宣传图片">
        <el-upload
          ref="uploadRef"
          :auto-upload="false"
          class="upload-demo"
          :show-file-list="true"
          :on-exceed="handleExceed"
          :limit="1"
          :on-change="onSelectFile"
          accept=".jpg,.png,.gif,.bmp"
        >
          <template #trigger>
            <el-button type="primary">选择图片</el-button>
          </template>
          <template #tip>
            <div class="el-upload__tip">请选择jpg/png/gif/bmp图片文件</div>
          </template>
        </el-upload>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="formSubmit">确认提交</el-button>
      </el-form-item>
    </el-form>
  </el-drawer>
  <!-- 景点多选框 -->
  <el-dialog v-model="multiSelect" :title="detailTitle">
    <el-table
      :data="multiSelectTableData"
      v-if="dataDrawerType === 'spot'"
      :border="true"
      height="250"
      style="width: 100%"
    >
      <el-table-column prop="SpotName" label="景点名称" />
      <el-table-column label="选择操作">
        <template #default="scoped">
          <el-button type="primary" @click="multiSelectHandle(scoped.row)">确定</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-table
      :data="multiSelectTableData"
      v-else-if="dataDrawerType === 'road'"
      :border="true"
      height="250"
      style="width: 100%"
    >
      <el-table-column prop="RoadName" label="路线名称" />
      <el-table-column label="选择操作">
        <template #default="scoped">
          <el-button type="primary" @click="multiSelectHandle(scoped.row)">确定</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-table
      :data="multiSelectTableData"
      v-else-if="dataDrawerType === 'area'"
      :border="true"
      height="250"
      style="width: 100%"
    >
      <el-table-column prop="AreaName" label="区域名称" />
      <el-table-column label="选择操作">
        <template #default="scoped">
          <el-button type="primary" @click="multiSelectHandle(scoped.row)">确定</el-button>
        </template>
      </el-table-column>
    </el-table>
  </el-dialog>
  <!-- 景点详情展示框 -->
  <el-dialog v-model="DetailDrawer" width="600px">
    <el-descriptions
      v-if="dataDrawerType === 'spot'"
      class="scenic-descriptions"
      title="景点详情"
      :column="1"
      size="large"
      :border="true"
      direction="vertical"
    >
      <template #extra>
        <el-button type="primary" @click="updateScenicGeometry('spot')">更新景点位置</el-button>
        <el-button type="primary" @click="updateScenicDetail()">更新景点详情</el-button>
        <el-button type="danger" @click="deleteScenic('spot')">删除景点</el-button>
      </template>

      <el-descriptions-item>
        <template #label>
          <div class="cell-item">
            <el-icon><moon-night /></el-icon>
            景点名称
          </div>
        </template>
        {{ spotData?.SpotName }}
      </el-descriptions-item>

      <el-descriptions-item>
        <template #label>
          <div class="cell-item">
            <el-icon><list /></el-icon>
            景点类型
          </div>
        </template>
        {{ spotData?.spotType || '未设置' }}
      </el-descriptions-item>

      <el-descriptions-item v-if="spotData?.SpotIntroduction">
        <template #label>
          <div class="cell-item">
            <el-icon><list /></el-icon>
            景点详细描述
          </div>
        </template>
        <div class="content-wrapper description-content">
          {{ spotData?.SpotIntroduction }}
        </div>
      </el-descriptions-item>

      <el-descriptions-item v-if="spotData?.IntroduceImageBase64">
        <template #label>
          <div class="cell-item">
            <el-icon><Picture></Picture></el-icon>
            景点宣传图片
          </div>
        </template>
        <div class="image-container">
          <el-image
            :src="spotData?.IntroduceImageBase64"
            :preview-src-list="[spotData?.IntroduceImageBase64]"
            fit="contain"
            class="spot-image"
          >
            <template #error>
              <div class="image-error">
                <el-icon><picture-filled /></el-icon>
                <span>加载失败</span>
              </div>
            </template>
          </el-image>
        </div>
      </el-descriptions-item>
    </el-descriptions>
    <el-descriptions
      v-if="dataDrawerType === 'road'"
      class="scenic-descriptions"
      title="道路详情"
      :column="1"
      size="large"
      :border="true"
      direction="vertical"
    >
      <template #extra>
        <el-button type="primary" @click="updateScenicGeometry('road')">更新道路位置</el-button>
        <el-button type="primary" @click="updateScenicDetail()">更新道路详情</el-button>
        <el-button type="danger" @click="deleteScenic('road')">删除道路</el-button>
      </template>

      <el-descriptions-item>
        <template #label>
          <div class="cell-item">
            <el-icon><moon-night /></el-icon>
            道路名称
          </div>
        </template>
        {{ roadData?.RoadName }}
      </el-descriptions-item>

      <el-descriptions-item v-if="roadData?.RoadIntroduction">
        <template #label>
          <div class="cell-item">
            <el-icon><list /></el-icon>
            道路详细描述
          </div>
        </template>
        <div class="description-content content-wrapper">
          {{ roadData?.RoadIntroduction }}
        </div>
      </el-descriptions-item>

      <el-descriptions-item v-if="roadData?.IntroduceImageBase64">
        <template #label>
          <div class="cell-item">
            <el-icon><Picture></Picture></el-icon>
            道路宣传图片
          </div>
        </template>
        <div class="image-container">
          <el-image
            :src="roadData?.IntroduceImageBase64"
            :preview-src-list="[roadData?.IntroduceImageBase64]"
            fit="contain"
            class="spot-image"
          >
            <template #error>
              <div class="image-error">
                <el-icon><picture-filled /></el-icon>
                <span>加载失败</span>
              </div>
            </template>
          </el-image>
        </div>
      </el-descriptions-item>
    </el-descriptions>
    <el-descriptions
      v-if="dataDrawerType === 'area'"
      class="scenic-descriptions"
      title="区域详情"
      :column="1"
      size="large"
      :border="true"
      direction="vertical"
    >
      <template #extra>
        <el-button type="primary" @click="updateScenicGeometry('area')">更新区域位置</el-button>
        <el-button type="primary" @click="updateScenicDetail()">更新区域详情</el-button>
        <el-button type="danger" @click="deleteScenic('area')">删除区域</el-button>
      </template>

      <el-descriptions-item>
        <template #label>
          <div class="cell-item">
            <el-icon><moon-night /></el-icon>
            区域名称
          </div>
        </template>
        {{ areaData?.AreaName }}
      </el-descriptions-item>

      <el-descriptions-item v-if="areaData?.AreaIntroduction">
        <template #label>
          <div class="cell-item">
            <el-icon><list /></el-icon>
            区域详细描述
          </div>
        </template>
        <div class="description-content content-wrapper">
          {{ areaData?.AreaIntroduction }}
        </div>
      </el-descriptions-item>

      <el-descriptions-item v-if="areaData?.IntroduceImageBase64">
        <template #label>
          <div class="cell-item">
            <el-icon><Picture></Picture></el-icon>
            区域宣传图片
          </div>
        </template>
        <div class="image-container">
          <el-image
            :src="areaData?.IntroduceImageBase64"
            :preview-src-list="[areaData?.IntroduceImageBase64]"
            fit="contain"
            class="spot-image"
          >
            <template #error>
              <div class="image-error">
                <el-icon><picture-filled /></el-icon>
                <span>加载失败</span>
              </div>
            </template>
          </el-image>
        </div>
      </el-descriptions-item>
    </el-descriptions>
  </el-dialog>

  <!-- 性能测试面板 -->
  <el-dialog v-model="showPerformancePanel" title="性能测试报告" width="800px">
    <div class="performance-controls">
      <el-button type="danger" size="small" @click="clearPerformanceRecords">
        清除性能记录
      </el-button>
    </div>
    <el-table :data="Object.entries(performanceReport).map(([key, value]) => ({key, ...value}))" border stripe>
      <el-table-column prop="key" label="操作名称" width="180" />
      <el-table-column prop="count" label="执行次数" width="100" />
      <el-table-column prop="average" label="平均耗时(ms)" width="120">
        <template #default="{row}">
          {{ row.average ? row.average.toFixed(2) : 0 }}
        </template>
      </el-table-column>
      <el-table-column prop="min" label="最小耗时(ms)" width="120">
        <template #default="{row}">
          {{ row.min ? row.min.toFixed(2) : 0 }}
        </template>
      </el-table-column>
      <el-table-column prop="max" label="最大耗时(ms)" width="120">
        <template #default="{row}">
          {{ row.max ? row.max.toFixed(2) : 0 }}
        </template>
      </el-table-column>
      <el-table-column prop="lastExecution" label="最近执行(ms)" width="120">
        <template #default="{row}">
          {{ row.lastExecution ? row.lastExecution.toFixed(2) : 0 }}
        </template>
      </el-table-column>
    </el-table>
    <div class="performance-tips">
      <p><strong>性能测试说明：</strong></p>
      <ul>
        <li>mapInitialization: 地图初始化时间</li>
        <li>addScenicSpot/Road/Area: 添加景点/道路/区域的操作时间</li>
        <li>query景点/道路/区域: 查询要素的时间</li>
        <li>submit景点/道路/区域: 提交要素数据的时间</li>
        <li>delete景点/道路/区域: 删除要素的时间</li>
      </ul>
      <p>注意：耗时过长的操作可能需要优化。一般来说，用户交互操作应在300ms内响应，以保证良好的用户体验。</p>
    </div>
  </el-dialog>
</template>

<style scoped>
.mapViewContainer {
  width: 100%;
  height: 100%;
  position: relative;
}

.function-panel {
  background: rgba(255, 255, 255, 0.95);
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  padding: 10px;
  margin: 10px;
  backdrop-filter: blur(10px);
}

.function-menu {
  border: none;
  background: transparent;
}

.menu-item {
  margin-bottom: 5px;
  transition: all 0.3s;
}

.menu-item:hover {
  background: rgba(64, 158, 255, 0.1);
  border-radius: 4px;
}

:deep(.el-sub-menu__title) {
  border-radius: 4px;
  height: 40px;
  line-height: 40px;
}

:deep(.el-menu-item) {
  border-radius: 4px;
  height: 36px;
  line-height: 36px;
}

.el-icon {
  margin-right: 8px;
  font-size: 16px;
}

.el-menu-vertical-demo {
  width: 150px;
  border-right: none;
}

.el-menu-vertical-demo .el-sub-menu .el-menu-item {
  min-width: 140px;
}

.el-menu-vertical-demo .el-sub-menu__title,
.el-menu-vertical-demo .el-menu-item {
  padding: 5px 10px;
}

.el-menu-vertical-demo .el-sub-menu {
  background-color: white;
}

.el-menu-vertical-demo .el-sub-menu .el-menu {
  background-color: white;
}

.scenic-descriptions {
  width: 100%;
}

.cell-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.cell-item .el-icon {
  font-size: 16px;
}

.content-wrapper {
  word-break: break-word; /* 确保长文本会换行 */
  white-space: pre-wrap; /* 保留空格和换行符 */
  max-width: 100%; /* 限制最大宽度 */
}



.description-content {
  white-space: pre-wrap;
  line-height: 1.5;
  padding: 8px 0;
}

.image-container {
  padding: 12px 0;
  display: flex;
  justify-content: center;
}

.spot-image {
  width: 300px;
  height: 200px;
  object-fit: contain;
  border-radius: 4px;
  cursor: pointer;
  transition: transform 0.3s ease;
}

.spot-image:hover {
  transform: scale(1.02);
}

.image-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #909399;
  font-size: 14px;
  gap: 8px;
}

:deep(.el-descriptions__body) {
  background-color: #fff;
}

:deep(.el-descriptions__label) {
  width: 120px;
  background-color: #f5f7fa;
}

:deep(.el-descriptions__content) {
  padding: 12px 16px;
}

.drawing-controls {
  margin-top: 10px;
  padding: 10px;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 4px;
  border: 1px solid #e4e7ed;
}

.drawing-tip {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  color: #409eff;
}

.drawing-tip .el-icon {
  margin-right: 5px;
}

.cancel-button {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.cancel-button .el-icon {
  margin-right: 5px;
}

/* 性能测试相关样式 */
.performance-button-container {
  margin-bottom: 10px;
  display: flex;
  justify-content: center;
}

.performance-controls {
  margin-bottom: 15px;
  display: flex;
  justify-content: flex-end;
}

.performance-tips {
  margin-top: 20px;
  padding: 15px;
  background-color: #f8f9fa;
  border-radius: 4px;
  font-size: 14px;
}

.performance-tips ul {
  margin: 10px 0;
  padding-left: 20px;
}

.performance-tips li {
  margin-bottom: 5px;
}
</style>
